home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / SerialIO.c < prev    next >
C/C++ Source or Header  |  1995-06-18  |  12KB  |  753 lines

  1. /*
  2. **    SerialIO.c
  3. **
  4. **    Serial read/write routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. STATIC LONG __aligned    ReadQueued    = FALSE,
  13.             WriteQueued    = FALSE;
  14.  
  15.     /* DeleteLED():
  16.      *
  17.      *    Dummy routine, the real implementation may
  18.      *    follow in a later release.
  19.      */
  20.  
  21. VOID
  22. DeleteLED()
  23. {
  24. }
  25.  
  26.     /* CreateLED():
  27.      *
  28.      *    Dummy routine, the real implementation may
  29.      *    follow in a later release.
  30.      */
  31.  
  32. VOID
  33. CreateLED()
  34. {
  35. }
  36.  
  37.     /* ResetSerialRead():
  38.      *
  39.      *    Reset the read status.
  40.      */
  41.  
  42. VOID
  43. ResetSerialRead()
  44. {
  45.     ReadQueued = FALSE;
  46. }
  47.  
  48.     /* CheckSerialRead():
  49.      *
  50.      *    Check if a read request is finished.
  51.      */
  52.  
  53. BOOLEAN
  54. CheckSerialRead()
  55. {
  56.     if(ReadRequest && ReadQueued)
  57.     {
  58.         if(CheckIO(ReadRequest))
  59.             return(TRUE);
  60.     }
  61.  
  62.     return(FALSE);
  63. }
  64.  
  65.     /* WaitSerialRead():
  66.      *
  67.      *    Wait for the read request to terminate.
  68.      */
  69.  
  70. BYTE
  71. WaitSerialRead()
  72. {
  73.     if(ReadRequest && ReadQueued)
  74.     {
  75.         ReadQueued = FALSE;
  76.  
  77.         return(WaitIO(ReadRequest));
  78.     }
  79.     else
  80.         return(0);
  81. }
  82.  
  83.     /* FlushSerialRead():
  84.      *
  85.      *    Forget about the current contents of the serial
  86.      *    read buffer.
  87.      */
  88.  
  89. VOID
  90. FlushSerialRead()
  91. {
  92.     if(ReadRequest)
  93.     {
  94.         BOOL WasRunning;
  95.  
  96.         if(WasRunning = ReadQueued)
  97.             StopSerialRead();
  98.  
  99.         ReadRequest -> IOSer . io_Command = CMD_CLEAR;
  100.  
  101.         DoIO(ReadRequest);
  102.  
  103.         if(WasRunning)
  104.             StartSerialRead(ReadBuffer,1);
  105.     }
  106. }
  107.  
  108.     /* StopSerialRead():
  109.      *
  110.      *    Force a read request to terminate.
  111.      */
  112.  
  113. VOID
  114. StopSerialRead()
  115. {
  116.     if(ReadRequest && ReadQueued)
  117.     {
  118.         if(!CheckIO(ReadRequest))
  119.             AbortIO(ReadRequest);
  120.  
  121.         WaitIO(ReadRequest);
  122.  
  123.         ReadQueued = FALSE;
  124.     }
  125. }
  126.  
  127.     /* StartSerialRead(register ULONG Length,register APTR Data):
  128.      *
  129.      *    Start a serial read request asynchronously.
  130.      */
  131.  
  132. VOID __regargs
  133. StartSerialRead(register APTR Data,register ULONG Length)
  134. {
  135.     if(ReadRequest)
  136.     {
  137.         if(ReadQueued)
  138.             StopSerialRead();
  139.  
  140.         ReadRequest -> IOSer . io_Command    = CMD_READ;
  141.         ReadRequest -> IOSer . io_Length    = Length;
  142.         ReadRequest -> IOSer . io_Data        = Data;
  143.  
  144.         ClrSignal(1L << ReadPort -> mp_SigBit);
  145.  
  146.         SendIO(ReadRequest);
  147.  
  148.         ReadQueued = TRUE;
  149.     }
  150. }
  151.  
  152.     /* DoSerialRead(register ULONG Length,register APTR Data):
  153.      *
  154.      *    Perform a read request synchronously.
  155.      */
  156.  
  157. BYTE __regargs
  158. DoSerialRead(register APTR Data,register ULONG Length)
  159. {
  160.     if(ReadRequest)
  161.     {
  162.         if(ReadQueued)
  163.             StopSerialRead();
  164.  
  165.         ReadRequest -> IOSer . io_Command    = CMD_READ;
  166.         ReadRequest -> IOSer . io_Length    = Length;
  167.         ReadRequest -> IOSer . io_Data        = Data;
  168.  
  169.         return(DoIO(ReadRequest));
  170.     }
  171.     else
  172.         return(IOERR_SELFTEST);
  173. }
  174.  
  175.     /* ResetSerialWrite():
  176.      *
  177.      *    Reset the write status.
  178.      */
  179.  
  180. VOID
  181. ResetSerialWrite()
  182. {
  183.     WriteQueued = FALSE;
  184. }
  185.  
  186.     /* CheckSerialWrite():
  187.      *
  188.      *    Check if a write request is finished.
  189.      */
  190.  
  191. BOOLEAN
  192. CheckSerialWrite()
  193. {
  194.     if(WriteRequest && WriteQueued)
  195.     {
  196.         if(!CheckIO(WriteRequest))
  197.             return(TRUE);
  198.     }
  199.  
  200.     return(FALSE);
  201. }
  202.  
  203.     /* WaitSerialWrite():
  204.      *
  205.      *    Wait for the write request to terminate.
  206.      */
  207.  
  208. BYTE
  209. WaitSerialWrite()
  210. {
  211.     if(WriteRequest && WriteQueued)
  212.     {
  213.         WriteQueued = FALSE;
  214.  
  215.         return(WaitIO(WriteRequest));
  216.     }
  217.     else
  218.         return(0);
  219. }
  220.  
  221.     /* StopSerialWrite():
  222.      *
  223.      *    Force a write request to terminate.
  224.      */
  225.  
  226. VOID
  227. StopSerialWrite()
  228. {
  229.     if(WriteRequest && WriteQueued)
  230.     {
  231.         if(!CheckIO(WriteRequest))
  232.             AbortIO(WriteRequest);
  233.  
  234.         WaitIO(WriteRequest);
  235.  
  236.         WriteQueued = FALSE;
  237.     }
  238. }
  239.  
  240.     /* StartSerialWrite(register ULONG Length,register APTR Data):
  241.      *
  242.      *    Start a serial write request asynchronously.
  243.      */
  244.  
  245. VOID __regargs
  246. StartSerialWrite(register APTR Data,register ULONG Length)
  247. {
  248.     if(WriteRequest)
  249.     {
  250.         if(WriteQueued)
  251.             StopSerialWrite();
  252.  
  253.         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  254.         WriteRequest -> IOSer . io_Length    = Length;
  255.         WriteRequest -> IOSer . io_Data        = Data;
  256.  
  257.         ClrSignal(1L << WriteRequest -> IOSer . io_Message . mn_ReplyPort -> mp_SigBit);
  258.  
  259.         SendIO(WriteRequest);
  260.  
  261.         WriteQueued = TRUE;
  262.     }
  263. }
  264.  
  265.     /* DoSerialWrite(register ULONG Length,register APTR Data):
  266.      *
  267.      *    Perform a write request synchronously.
  268.      */
  269.  
  270. BYTE __regargs
  271. DoSerialWrite(register APTR Data,register ULONG Length)
  272. {
  273.     if(WriteRequest)
  274.     {
  275.         if(WriteQueued)
  276.             StopSerialWrite();
  277.  
  278.         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  279.         WriteRequest -> IOSer . io_Length    = Length;
  280.         WriteRequest -> IOSer . io_Data        = Data;
  281.  
  282.         return(DoIO(WriteRequest));
  283.     }
  284.     else
  285.         return(IOERR_SELFTEST);
  286. }
  287.  
  288.     /* DoSerialCmd(register UWORD Command):
  289.      *
  290.      *    Perform single command.
  291.      */
  292.  
  293. BYTE __regargs
  294. DoSerialCmd(register UWORD Command)
  295. {
  296.     if(WriteRequest)
  297.     {
  298.         if(WriteQueued)
  299.             StopSerialWrite();
  300.  
  301.         WriteRequest -> IOSer . io_Command = Command;
  302.  
  303.         return(DoIO(WriteRequest));
  304.     }
  305.     else
  306.         return(IOERR_SELFTEST);
  307. }
  308.  
  309.     /* GetSerialWaiting():
  310.      *
  311.      *    Query the number of bytes still waiting to be read
  312.      *    from the serial port.
  313.      */
  314.  
  315. ULONG
  316. GetSerialWaiting()
  317. {
  318.     if(WriteRequest)
  319.     {
  320.         if(WriteQueued)
  321.             StopSerialWrite();
  322.  
  323.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  324.  
  325.         DoIO(WriteRequest);
  326.  
  327.         return(WriteRequest -> IOSer . io_Actual);
  328.     }
  329.     else
  330.         return(0);
  331. }
  332.  
  333.     /* GetSerialStatus():
  334.      *
  335.      *    Query the current serial port status.
  336.      */
  337.  
  338. UWORD
  339. GetSerialStatus()
  340. {
  341.     if(WriteRequest)
  342.     {
  343.         if(WriteQueued)
  344.             StopSerialWrite();
  345.  
  346.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  347.  
  348.         DoIO(WriteRequest);
  349.  
  350.         return(WriteRequest -> io_Status);
  351.     }
  352.     else
  353.         return(CIAF_COMCD | CIAF_COMDSR);
  354. }
  355.  
  356.     /* GetSerialInfo(register ULONG *Waiting,register UWORD *Status):
  357.      *
  358.      *    Query both the number of bytes waiting to be read and
  359.      *    the current serial status.
  360.      */
  361.  
  362. VOID __regargs
  363. GetSerialInfo(register ULONG *Waiting,register UWORD *Status)
  364. {
  365.     if(WriteRequest)
  366.     {
  367.         if(WriteQueued)
  368.             StopSerialWrite();
  369.  
  370.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  371.  
  372.         DoIO(WriteRequest);
  373.  
  374.         *Waiting    = WriteRequest -> IOSer . io_Actual;
  375.         *Status        = WriteRequest -> io_Status;
  376.     }
  377.     else
  378.     {
  379.         *Waiting    = 0;
  380.         *Status        = CIAF_COMCD | CIAF_COMDSR;
  381.     }
  382. }
  383.  
  384.     /* SetSerialAttributes():
  385.      *
  386.      *    Set the serial driver attributes.
  387.      */
  388.  
  389. STATIC VOID
  390. SetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
  391. {
  392.     struct TagItem *Tag;
  393.  
  394.     while(Tag = NextTagItem(&Tags))
  395.     {
  396.         switch(Tag -> ti_Tag)
  397.         {
  398.             case SERA_Baud:
  399.  
  400.                 Request -> io_Baud = Tag -> ti_Data;
  401.                 break;
  402.  
  403.             case SERA_BreakTime:
  404.  
  405.                 Request -> io_BrkTime = Tag -> ti_Data;
  406.                 break;
  407.  
  408.             case SERA_BitsPerChar:
  409.  
  410.                 Request -> io_ReadLen    = Tag -> ti_Data;
  411.                 Request -> io_WriteLen    = Tag -> ti_Data;
  412.                 break;
  413.  
  414.             case SERA_StopBits:
  415.  
  416.                 Request -> io_StopBits = Tag -> ti_Data;
  417.                 break;
  418.  
  419.             case SERA_BufferSize:
  420.  
  421.                 Request -> io_RBufLen = Tag -> ti_Data;
  422.                 break;
  423.  
  424.             case SERA_Parity:
  425.  
  426.                 Request -> io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
  427.                 Request -> io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
  428.  
  429.                 switch(Tag -> ti_Data)
  430.                 {
  431.                     case PARITY_EVEN:
  432.  
  433.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  434.                         break;
  435.  
  436.                     case PARITY_ODD:
  437.  
  438.                         Request -> io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
  439.                         break;
  440.  
  441.                     case PARITY_MARK:
  442.  
  443.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  444.                         Request -> io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
  445.                         break;
  446.  
  447.                     case PARITY_SPACE:
  448.  
  449.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  450.                         Request -> io_ExtFlags |= SEXTF_MSPON;
  451.                         break;
  452.                 }
  453.  
  454.                 break;
  455.  
  456.             case SERA_Handshaking:
  457.  
  458.                 if(Tag -> ti_Data == HANDSHAKING_NONE)
  459.                     Request -> io_SerFlags &= ~SERF_7WIRE;
  460.                 else
  461.                     Request -> io_SerFlags |=  SERF_7WIRE;
  462.  
  463.                 break;
  464.  
  465.             case SERA_HighSpeed:
  466.  
  467.                 if(Tag -> ti_Data)
  468.                     Request -> io_SerFlags |=  SERF_RAD_BOOGIE;
  469.                 else
  470.                     Request -> io_SerFlags &= ~SERF_RAD_BOOGIE;
  471.  
  472.                 break;
  473.  
  474.             case SERA_Shared:
  475.  
  476.                 if(Tag -> ti_Data)
  477.                     Request -> io_SerFlags |=  SERF_SHARED;
  478.                 else
  479.                     Request -> io_SerFlags &= ~SERF_SHARED;
  480.  
  481.                 break;
  482.         }
  483.     }
  484.  
  485.     Request -> io_SerFlags |= SERF_XDISABLED;
  486. }
  487.  
  488.     /* GetSerialAttributes():
  489.      *
  490.      *    Get the serial driver attributes.
  491.      */
  492.  
  493. STATIC ULONG
  494. GetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
  495. {
  496.     struct TagItem    *Tag;
  497.     ULONG        *Data,
  498.              Result = NULL;
  499.  
  500.     while(Tag = NextTagItem(&Tags))
  501.     {
  502.         if(!(Data = (ULONG *)Tag -> ti_Data))
  503.             Data = &Result;
  504.  
  505.         switch(Tag -> ti_Tag)
  506.         {
  507.             case SERA_Baud:
  508.  
  509.                 *Data = Request -> io_Baud;
  510.                 break;
  511.  
  512.             case SERA_BreakTime:
  513.  
  514.                 *Data = Request -> io_BrkTime;
  515.                 break;
  516.  
  517.             case SERA_BitsPerChar:
  518.  
  519.                 *Data = Request -> io_ReadLen;
  520.                 break;
  521.  
  522.             case SERA_StopBits:
  523.  
  524.                 *Data = Request -> io_StopBits;
  525.                 break;
  526.  
  527.             case SERA_BufferSize:
  528.  
  529.                 *Data = Request -> io_RBufLen;
  530.                 break;
  531.  
  532.             case SERA_Parity:
  533.  
  534.                 Request -> io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
  535.                 Request -> io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
  536.  
  537.                 switch(Tag -> ti_Data)
  538.                 {
  539.                     case PARITY_EVEN:
  540.  
  541.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  542.                         break;
  543.  
  544.                     case PARITY_ODD:
  545.  
  546.                         Request -> io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
  547.                         break;
  548.  
  549.                     case PARITY_MARK:
  550.  
  551.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  552.                         Request -> io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
  553.                         break;
  554.  
  555.                     case PARITY_SPACE:
  556.  
  557.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  558.                         Request -> io_ExtFlags |= SEXTF_MSPON;
  559.                         break;
  560.                 }
  561.  
  562.                 switch(Request -> io_ExtFlags & (SEXTF_MSPON | SEXTF_MARK))
  563.                 {
  564.                     case SEXTF_MSPON | SEXTF_MARK:
  565.  
  566.                         *Data = PARITY_MARK;
  567.                         break;
  568.  
  569.                     case SEXTF_MSPON:
  570.  
  571.                         *Data = PARITY_SPACE;
  572.                         break;
  573.  
  574.                     default:
  575.  
  576.                         switch(Request -> io_SerFlags & (SERF_PARTY_ON | SERF_PARTY_ODD))
  577.                         {
  578.                             case SERF_PARTY_ON | SERF_PARTY_ODD:
  579.  
  580.                                 *Data = PARITY_ODD;
  581.                                 break;
  582.  
  583.                             case SERF_PARTY_ON:
  584.  
  585.                                 *Data = PARITY_EVEN;
  586.                                 break;
  587.  
  588.                             default:
  589.  
  590.                                 *Data = PARITY_NONE;
  591.                                 break;
  592.                         }
  593.  
  594.                         break;
  595.                 }
  596.  
  597.                 break;
  598.  
  599.             case SERA_Handshaking:
  600.  
  601.                 if(Request -> io_SerFlags & SERF_7WIRE)
  602.                     *Data = TRUE;
  603.                 else
  604.                     *Data = FALSE;
  605.  
  606.                 break;
  607.  
  608.             case SERA_HighSpeed:
  609.  
  610.                 if(Request -> io_SerFlags & SERF_RAD_BOOGIE)
  611.                     *Data = TRUE;
  612.                 else
  613.                     *Data = FALSE;
  614.  
  615.                 break;
  616.  
  617.             case SERA_Shared:
  618.  
  619.                 if(Request -> io_SerFlags & SERF_SHARED)
  620.                     *Data = TRUE;
  621.                 else
  622.                     *Data = FALSE;
  623.  
  624.                 break;
  625.         }
  626.     }
  627.  
  628.     return(Result);
  629. }
  630.  
  631.     /* SetBothSerialAttributes():
  632.      *
  633.      *    Set the serial read driver parameters.
  634.      */
  635.  
  636. BYTE __stdargs
  637. SetBothSerialAttributes(Tag FirstTag,...)
  638. {
  639.     if(ReadRequest && WriteRequest)
  640.     {
  641.         BYTE Result;
  642.  
  643.         if(ReadQueued)
  644.             StopSerialRead();
  645.  
  646.         if(WriteQueued)
  647.             StopSerialWrite();
  648.  
  649.         SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
  650.  
  651.         if(ReadRequest -> IOSer . io_Device)
  652.         {
  653.             ReadRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  654.  
  655.             Result = DoIO(ReadRequest);
  656.         }
  657.         else
  658.             Result = 0;
  659.  
  660.         if(!Result)
  661.         {
  662.             struct MsgPort *WritePort = WriteRequest -> IOSer . io_Message . mn_ReplyPort;
  663.  
  664.             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  665.  
  666.             WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  667.         }
  668.  
  669.         return(Result);
  670.     }
  671.     else
  672.         return(IOERR_SELFTEST);
  673. }
  674.  
  675.     /* SetSerialReadAttributes():
  676.      *
  677.      *    Set the serial read driver parameters.
  678.      */
  679.  
  680. BYTE __stdargs
  681. SetSerialReadAttributes(Tag FirstTag,...)
  682. {
  683.     if(ReadRequest)
  684.     {
  685.         if(ReadQueued)
  686.             StopSerialRead();
  687.  
  688.         SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
  689.  
  690.         if(ReadRequest -> IOSer . io_Device)
  691.         {
  692.             ReadRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  693.  
  694.             return(DoIO(ReadRequest));
  695.         }
  696.         else
  697.             return(0);
  698.     }
  699.     else
  700.         return(IOERR_SELFTEST);
  701. }
  702.  
  703.     /* SetSerialWriteAttributes():
  704.      *
  705.      *    Set the serial write driver parameters.
  706.      */
  707.  
  708. BYTE __stdargs
  709. SetSerialWriteAttributes(Tag FirstTag,...)
  710. {
  711.     if(WriteRequest)
  712.     {
  713.         if(WriteQueued)
  714.             StopSerialWrite();
  715.  
  716.         SetSerialAttributes(WriteRequest,(struct TagItem *)&FirstTag);
  717.  
  718.         WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  719.  
  720.         return(DoIO(WriteRequest));
  721.     }
  722.     else
  723.         return(IOERR_SELFTEST);
  724. }
  725.  
  726.     /* GetSerialReadAttributes():
  727.      *
  728.      *    Get the serial read driver parameters.
  729.      */
  730.  
  731. ULONG __stdargs
  732. GetSerialReadAttributes(Tag FirstTag,...)
  733. {
  734.     if(ReadRequest)
  735.         return(GetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag));
  736.     else
  737.         return(NULL);
  738. }
  739.  
  740.     /* GetSerialWriteAttributes():
  741.      *
  742.      *    Get the serial write driver parameters.
  743.      */
  744.  
  745. ULONG __stdargs
  746. GetSerialWriteAttributes(Tag FirstTag,...)
  747. {
  748.     if(WriteRequest)
  749.         return(GetSerialAttributes(WriteRequest,(struct TagItem *)&FirstTag));
  750.     else
  751.         return(NULL);
  752. }
  753.